package br.com.equipe1.model.service;

import java.util.List;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;

import org.joda.time.DateTime;

import br.com.equipe1.model.Representante;
import br.com.equipe1.utils.FacesUtils;

public class RepresentanteService {
	
	private final static String PERSISTENCE_UNIT_NAME = "Projeto";
	private static final String NOME = "nome";
	private static final String DATA_ANIVERSARIO = "dataAniversario";
	private static final String EMAIL = "email";	
	private EntityManager entityManager;
	private EntityManagerFactory factory;
	
	public RepresentanteService() {
		factory = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
	}

	public EntityManager getEntityManager() {
		return factory.createEntityManager();
	}
	
	public void salvar(Representante representante){
		try {
			entityManager = getEntityManager();
			entityManager.getTransaction().begin();
			if(representante.getId() == null){
				entityManager.persist(representante);	
				FacesUtils.info("Representante "+representante.getNome()+" adicionado com sucesso.");
			} else {
				entityManager.merge(representante);
				FacesUtils.info("Representante "+representante.getNome()+" atualizado com sucesso.");
			}
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			FacesUtils.error("Erro ao salvar representante. Contate administrador");
			e.printStackTrace();
			entityManager.getTransaction().rollback();
		} finally {
			entityManager.close();
		}
	}
	
	public void remover(Integer id){
		try {
			entityManager = getEntityManager();
			entityManager.getTransaction().begin();
			Representante representante = null;
			representante = entityManager.getReference(Representante.class, id);
			entityManager.remove(representante);
			entityManager.getTransaction().commit();
		} catch (Exception e) {
			FacesUtils.error("Erro ao remover representante. Contate administrador");
			e.printStackTrace();
			entityManager.getTransaction().rollback();
		} finally {
			entityManager.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Representante> buscarTodos(){
		entityManager = getEntityManager();
		try {
			StringBuilder sql = new StringBuilder();
			sql.append(" SELECT rep FROM Representante rep ");
			sql.append(" INNER JOIN FETCH rep.cargo car ");
			sql.append(" INNER JOIN FETCH rep.enderecoRepresentante er ");
			sql.append(" ORDER BY rep.nome ");
			return entityManager.createQuery(sql.toString()).getResultList();			
			
		} finally {
			entityManager.close();
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Representante> buscarPorFiltro(Map<String, Object> filtro){
		entityManager = getEntityManager();
		try {
			StringBuilder sql = new StringBuilder();
			sql.append(" SELECT rep FROM Representante rep ");
			sql.append(" INNER JOIN FETCH rep.cargo car ");
			sql.append(" INNER JOIN FETCH rep.enderecoRepresentante er ");
			sql.append(" WHERE 1 = 1 ");
			sql.append(!isNomeNulo(filtro) ? " AND UPPER(rep.nome) LIKE UPPER(:nome) " : "");
			sql.append(!isDataAniversarioNulo(filtro) ? " AND DAY(rep.dataNascimento) = :dataAniversarioDia AND MONTH(rep.dataNascimento) = :dataAniversarioMes " : "");
			sql.append(!isEmailNulo(filtro) ? " AND UPPER(rep.email) LIKE UPPER(:email) " : "");
			sql.append(" ORDER BY rep.nome ");
			Query query = entityManager.createQuery(sql.toString());
			if(!isNomeNulo(filtro)){
				query.setParameter(NOME, "%" + filtro.get(NOME).toString() + "%");
			}
			if(!isDataAniversarioNulo(filtro)){
				query.setParameter("dataAniversarioDia", new DateTime(filtro.get(DATA_ANIVERSARIO)).getDayOfMonth());
				query.setParameter("dataAniversarioMes", new DateTime(filtro.get(DATA_ANIVERSARIO)).getMonthOfYear());
			}
			if(!isEmailNulo(filtro)){
				query.setParameter(EMAIL, "%"+filtro.get(EMAIL)+"%");
			}
			return query.getResultList();			
			
		} finally {
			entityManager.close();
		}		
	}
	
	private boolean isNomeNulo(Map<String, Object> filtro){
		return filtro.get(NOME) == "";
	}
	
	private boolean isDataAniversarioNulo(Map<String, Object> filtro){
		return filtro.get(DATA_ANIVERSARIO) == null;
	}
	
	private boolean isEmailNulo(Map<String, Object> filtro){
		return filtro.get(EMAIL) == "";
	}
}
